-
-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add type argument to S.get, S.gets, and S.pluck #64
Conversation
This should be really useful @davidchambers! I think saying |
//. value `true` is also considered "true". Other types must provide | ||
//. if the first is “true”; the first value otherwise. An array is | ||
//. considered “true” if its length is greater than zero. The Boolean | ||
//. value `true` is also considered “true”. Other types must provide |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the fancy quotation marks be a part of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to use curly quotes around “plucking”, and wanted to be consistent. I'll switch to curly quotes in a separate pull request then rebase this branch. :)
You could use the syntax for a class constraint. get :: Type a => Type -> String -> Accessible -> Maybe a |
Since |
I think you have to be the type checker in this case. Look at where It is sent to In It also is used as the RHS of Combine the two types and you end up with something like: So putting it all together you get something like: get :: (() -> (Accessible | a)) -> String -> Accessible -> Maybe a |
@joneshf, I don't understand how you arrived at > String(42)
'42'
> String(null)
'null' This suggests we have something like How about this? get :: A -> String -> Accessible -> Maybe a This would mean we're treating single-letter identifiers—rather than lower-case identifiers—as type variables. This is a deviation from Haskell, but the correspondence between |
One thing that might work is
This is more exact since the values like We can imagine an indexed family of types of kind |
@tel, are you suggesting that |
Yeah, exactly! We cannot instantiate this type directly in Haskell, but it'd look a bit like this data TypeRep a where
Number :: TypeRep Number
Array :: TypeRep a -> TypeRep (Array a)
... The difficulty is that in Haskell we need to ultimately close the type (end it after finitely many variants have been specified) yet we're allowed to continue specifying new types afterward. Worse, there's no way to get values at But ignoring those issues that's the exact idea. |
5cdc3c7
to
5fef867
Compare
Okay. I like the idea. Do these changes seem right? - is :: Type -> a -> Boolean
+ is :: Type a -> b -> Boolean
- Maybe :: Type
+ Maybe :: Type Maybe
- Maybe#type :: Type
+ Maybe#type :: Type Maybe
- Either :: Type
+ Either :: Type Either
- Either#type :: Type
+ Either#type :: Type Either
- pluck :: String -> [{String: *}] -> [Maybe *]
+ pluck :: Type a -> String -> [Accessible] -> [Maybe a]
- get :: String -> Object -> Maybe *
+ get :: Type a -> String -> Accessible -> Maybe a
- gets :: [String] -> Object -> Maybe *
+ gets :: Type a -> [String] -> Accessible -> Maybe a Unless there's a compelling reason to use |
I suppose those work, but using |
Yeah, |
2156e2c
to
8c0555b
Compare
//. Number :: TypeRep Number | ||
//. | ||
//. `Number` is the sole inhabitant of the TypeRep Number type. | ||
//. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this convey the idea, @tel? Are there any wording changes you think would make this section clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds great! Two minor points alone
- "...
Number
is really the..." may be better said as "Number
acts as the..." TypeRep
can be called a "type function" or "type constructor" if you like instead of invoking the term "pseudotype". Taken together,TypeRep
might also be called a family of types or a fiber bundle... though that last term is quite rare!
👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback. :)
"...
Number
is really the..." may be better said as "Number
acts as the..."
I was about to :+1:
when I realized that if a representative is one who acts on behalf of another, acts as the representative of X can be expanded to acts as the one who acts on behalf of X. Perhaps I'm overthinking things. :)
TypeRep
can be called a "type function" or "type constructor" if you like instead of invoking the term "pseudotype".
Type constructor sounds good to me. I used the term "pseudotype" in #62:
The Int pseudotype represents integers in the range [-2^31 .. 2^31). It is a pseudotype because each Int is represented by a Number value. Sanctuary's run-time type checking asserts that a valid Number value is provided wherever an Int value is required.
I wanted a term to describe a thing which is a type in the sense of a set of values but not in the sense of typeof
or instanceof
. I reused the term in this pull request to describe Accessible, and later TypeRep.
Describing TypeRep as a type constructor makes its role clearer. We can use the following subheadings:
### Accessible pseudotype
### TypeRep type constructor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to use ### Type representatives
as the subheading instead.
I've changed occurrences of Setting aside type signatures for a moment, do others agree with the API change in question? Do you find the rationale compelling, @svozza? |
I definitely like this, the main issue I used to have with |
e7b2e3e
to
1ff8bcb
Compare
1ff8bcb
to
d0a93f5
Compare
add type argument to S.get, S.gets, and S.pluck
The fact that
S.get
returns a value of typeMaybe *
has bothered me for some time. I find myself filtering the result to ensure I have a value of the expected type. For example:This pull request adds a type specifier to
S.get
,S.gets
, andS.pluck
. The above will become:The current loose behaviour can be approximated by
S.get(Object)
. It's no longer possible to get null/undefined values. If this is important we could export an Any pseudotype, where Any contains every JavaScript value. Unless there's a use case, I'd prefer not to export and documentS.Any
.These changes build upon the foundation laid by #63. I've included a section explaining the Accessible pseudotype, as it's now used in type signatures.
One question I have is how to link
Type
anda
in a signature such as:Any suggestions?